﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.Linq;

namespace Columbus
{
    public class ApplicationSettings : IApplicationSettings
    {
        private readonly IDictionary<string, object> transientStore = new Dictionary<string, object>();
        private readonly IDictionary<string, object> backupTransientStore = new Dictionary<string, object>();
        private bool isEditing;

        public void Persist()
        {
            foreach (var transientStoreSetting in transientStore)
            {
                if (IsolatedStorageSettings.ApplicationSettings.Contains(transientStoreSetting.Key))
                    IsolatedStorageSettings.ApplicationSettings[transientStoreSetting.Key] = transientStoreSetting.Value;
                else
                    IsolatedStorageSettings.ApplicationSettings.Add(transientStoreSetting.Key,
                                                                    transientStoreSetting.Value);
            }
        }

        public void Restore()
        {
            foreach (var isolatedStorageSetting in IsolatedStorageSettings.ApplicationSettings)
            {
                transientStore.Add(isolatedStorageSetting.Key, isolatedStorageSetting.Value);
            }
        }

        public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
        {
            return transientStore.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public bool TryGetValue(string key, out object value)
        {
            return transientStore.TryGetValue(key, out value);
        }

        public bool Remove(string key)
        {
            return transientStore.Remove(key);
        }

        public void Clear()
        {
            transientStore.Clear();
        }

        public bool IsEditing
        {
            get { return isEditing; }
        }

        public ICollection<string> Keys
        {
            get { return transientStore.Keys; }
        }

        public ICollection<object> Values
        {
            get { return transientStore.Values; }
        }

        public int Count
        {
            get { return transientStore.Count; }
        }

        public void Add(string key, object objectToSave)
        {
            transientStore.Add(key, objectToSave);
        }

        public bool Contains(string key)
        {
            return transientStore.ContainsKey(key);
        }

        public object this[string key]
        {
            get { return transientStore[key]; }
            set { transientStore[key] = value; }
        }

        public void BeginEdit()
        {
            backupTransientStore.Clear();
            transientStore.CopyTo(backupTransientStore.ToArray(), 0);
            isEditing = true;
        }

        public void EndEdit()
        {
            if (!isEditing)
                throw new InvalidOperationException("Application settings must be in edit mode to end edit");
            backupTransientStore.Clear();
            isEditing = false;
        }

        public void CancelEdit()
        {
            if (!isEditing)
                throw new InvalidOperationException("Application settings must be in edit mode to cancel edit");
            backupTransientStore.CopyTo(transientStore.ToArray(), 0);
            isEditing = false;
        }
    }
}